www.gusucode.com > 基于Visual C++高级界面特效制作百例源码程序 > 基于Visual C++高级界面特效制作百例源码程序/code/char11/pushpin/PushPin.cpp
/* Module : PUSHPIN.H Purpose: Implementation of a push pin button (as seen on X-Windows & property dialogs in VC 4) Created: PJN / 04-04-1996 History: PJN / 08-06-1996 / Removed win32sup.h include PJN / 20-11-1997 / Major Update to code, changes include 1. Support non default color schemes 2. Supports dynamic changes to color schemes 3. Complete restructuring of code 4. Can now use an edged bitmap if you want to 5. Dropped support for Win16 6. Redid the example program 7. Simplified external usage of class PJN / 24-11-1997 1. Minor changes to support CPushPinFrame class PJN / 07-12-1997 Minor changes to fix a small redraw bug Copyright (c) 1997 by PJ Naughter. All rights reserved. */ ///////////////////////////////// Includes ////////////////////////////////// #include "stdafx.h" #include "resource.h" #include "PushPin.h" ////////////////////////////////// Macros /////////////////////////////////// #ifdef _DEBUG #undef THIS_FILE static char BASED_CODE THIS_FILE[] = __FILE__; #define new DEBUG_NEW #endif ////////////////////////////////// Implementation ///////////////////////////// BEGIN_MESSAGE_MAP(CPushPinButton, CButton) //{{AFX_MSG_MAP(CPushPinButton) //}}AFX_MSG_MAP ON_CONTROL_REFLECT(BN_CLICKED, OnClicked) END_MESSAGE_MAP() CPushPinButton::CPushPinButton() { m_bPinned = FALSE; m_bUseEdge = FALSE; m_MaxRect = CRect(0, 0, 0, 0); LoadBitmaps(); } void CPushPinButton::ReloadBitmaps() { //free the bitmap resources m_PinnedBitmap.DeleteObject(); m_UnPinnedBitmap.DeleteObject(); //Reload the bitmaps LoadBitmaps(); //size to content SizeToContent(); //Invalidate the maximum rect of the pushpin on the parent window GetParent()->InvalidateRect(m_MaxRect); //Force this button to redraw aswell Invalidate(); } void CPushPinButton::LoadBitmaps() { if (m_bUseEdge) { BOOL bLoad = m_PinnedBitmap.Attach((HBITMAP) LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDB_PINNEDEDGE_BITMAP), IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS)); ASSERT(bLoad); bLoad = m_UnPinnedBitmap.Attach((HBITMAP) LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDB_UNPINNEDEDGE_BITMAP), IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS)); ASSERT(bLoad); } else { BOOL bLoad = m_PinnedBitmap.Attach((HBITMAP) LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDB_PINNED_BITMAP), IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS)); ASSERT(bLoad); bLoad = m_UnPinnedBitmap.Attach((HBITMAP) LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDB_UNPINNED_BITMAP), IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS)); ASSERT(bLoad); } } void CPushPinButton::DrawItem(LPDRAWITEMSTRUCT lpDIS) { ASSERT(lpDIS != NULL); //select the bitmap CBitmap* pBitmap; if (m_bPinned) pBitmap = &m_PinnedBitmap; else pBitmap = &m_UnPinnedBitmap; // draw the whole button CDC* pDC = CDC::FromHandle(lpDIS->hDC); CDC memDC; memDC.CreateCompatibleDC(pDC); CBitmap* pOld = memDC.SelectObject(pBitmap); if (pOld == NULL) return; // destructors will clean up CRect rect; rect.CopyRect(&lpDIS->rcItem); pDC->BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &memDC, 0, 0, SRCCOPY); memDC.SelectObject(pOld); } void CPushPinButton::SetPinned(BOOL bPinned) { m_bPinned = bPinned; Invalidate(); } void CPushPinButton::SetUseEdgeBitmap(BOOL bUseEdge) { if (bUseEdge == m_bUseEdge) //quick return return; m_bUseEdge = bUseEdge; //toggle the option, reload and ReloadBitmaps(); //and force a redraw } void CPushPinButton::OnClicked() { m_bPinned = !m_bPinned; //toggle the pinned option Invalidate(); //and force a redraw } void CPushPinButton::PreSubclassWindow() { CButton::PreSubclassWindow(); //button must be owner draw ASSERT(GetWindowLong(m_hWnd, GWL_STYLE) & BS_OWNERDRAW); //size to content SizeToContent(); } void CPushPinButton::SizeToContent() { ASSERT(m_PinnedBitmap.m_hObject != NULL); CSize bitmapSize; BITMAP bmInfo; VERIFY(m_PinnedBitmap.GetObject(sizeof(bmInfo), &bmInfo) == sizeof(bmInfo)); //Calculate the client rect in parent coordinates of the maximum size of the pushpin button m_MaxRect = CRect(0, 0, max(bmInfo.bmWidth, m_MaxRect.Width()), max(bmInfo.bmHeight, m_MaxRect.Height())); ClientToScreen(&m_MaxRect); CPoint p1(m_MaxRect.left, m_MaxRect.top); CPoint p2(m_MaxRect.right, m_MaxRect.bottom); HWND hParent = ::GetParent(m_hWnd); ::ScreenToClient(hParent, &p1); ::ScreenToClient(hParent, &p2); m_MaxRect = CRect(p1, p2); //resize the button to match the size of the bitmap VERIFY(SetWindowPos(NULL, -1, -1, bmInfo.bmWidth, bmInfo.bmHeight, SWP_NOMOVE|SWP_NOZORDER|SWP_NOREDRAW|SWP_NOACTIVATE)); }